/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
/**
 *
 * $Id: IMUTypes.hpp,v 1.5 2009-05-13 07:18:17 amaula Exp $
 *
 * \file
 * \brief MaCI - IMU Interface Type definition header
 * \author Matthieu Myrsky <matthieu.myrsky@tkk.fi>
 *
 */
#ifndef _MACI_IMUTYPES_HPP_
#define _MACI_IMUTYPES_HPP_
#include <inttypes.h>
#include "timestamp.hpp"

namespace MaCI {

  /** MaCI - IMU interface.
   *
   * This namespace contains all types, methods and helper classes
   * for implementing a IMU interface for MaCI.
   */
  namespace IMU {
    enum EIMUType { 
      KTypeUnknown              =-1, ///< Unknown type
      KTypeTimestamp            = 0, ///< Contains Common::Timestamp
      KTypeAcceleration3d       = 1, ///< Contains TAcceleration3D
      KTypeAngularVelocity3d    = 2, ///< Contains TAngularVelocity3D
      KTypeAngle3d              = 3, ///< Contains TAngle3D
      KTypeQuaternion           = 4, ///< Contains TQuaternion
      KTypeOrientationMatrix    = 5, ///< Contains TOrientationMatrix
      KTypeEventTypes           = 8, ///< Contains TEventTypes
      KTypeCommand              = 9  ///< Contains TCommand
    };

    /** IMU commands.
     *
     * IMU commands for the 'TCommand' structure. Defined in global
     * 'IMU' namespace because otherwise l^Husers would complain :)
     */
    enum EIMUCommand { 
      KCommandUnknown                      = 0, ///< Unkown command
      KCommandGetAcceleration3d            = 1, ///< Get TAcceleration3D
      KCommandGetAngularVelocity3d         = 2, ///< Get TAngularVelocity3D
      KCommandGetAngle3d                   = 3, ///< Get TAngle3D
      KCommandGetQuaternion                = 4, ///< Get TQuaternion
      KCommandGetOrientationMatrix         = 5, ///< Get OrientationMatrix
      KCommandEvent                        = 8, ///< Event
      KCommandGetEventTypes                = 9,
      KCommandGetEventTypesReply           = 10,
      KCommandGetAcceleration3dReply       = 11, ///< Get TAcceleration3D reply
      KCommandGetAngularVelocity3dReply    = 12, ///< Get TAngularVelocity3D reply
      KCommandGetAngle3dReply              = 13, ///< Get TAngle3D reply
      KCommandGetQuaternionReply           = 14, ///< Get TQuaternion reply
      KCommandGetOrientationMatrixReply    = 15    ///< Get OrientationMatrix reply
    };

    /**
     * Defines which types are sended continuously
     */
    struct TEventTypes
    {
      TEventTypes(const unsigned int aContinuousTypes = 0)
        : continuousTypes(aContinuousTypes){}

      uint32_t continuousTypes;    ///< continuous types, saved in bits. shifted by proper EIMUType


    };    

    /**
     * Defines acceleration in 3 direction
     */
    struct TAcceleration3d
    {
      TAcceleration3d(const float aAccelerationX = 0.0,
		      const float aAccelerationY = 0.0,
		      const float aAccelerationZ = 0.0)
	: accelerationX(aAccelerationX),
	  accelerationY(aAccelerationY),
	  accelerationZ(aAccelerationZ){}

      float accelerationX;   ///< Acceleration in x-direction
      float accelerationY;   ///< Acceleration in y-direction
      float accelerationZ;   ///< Acceleration in z-direction
    };

    /**
     * Defines angular velocities in three direction
     */
    struct TAngularVelocity3d
    {
      TAngularVelocity3d(const float aAngularVelocityX = 0.0,
		  const float aAngularVelocityY = 0.0,
		  const float aAngularVelocityZ = 0.0)
	: wX(aAngularVelocityX),
	  wY(aAngularVelocityY),
	  wZ(aAngularVelocityZ){}

      float wX;    ///< angular velocity around x-axis
      float wY;    ///< angular velocity around y-axis
      float wZ;    ///< angular velocity around z-axis
    };


    /**
     * Defines angle in three direction
     */
    struct TAngle3d
    {
      TAngle3d(const float aRoll = 0.0,
	       const float aPitch = 0.0,
	       const float aYaw = 0.0)
	: roll(aRoll),
	  pitch(aPitch),
	  yaw(aYaw){}

      float roll;     ///< roll angle
      float pitch;    ///< pitch angle
      float yaw;      ///< yaw angle
    };

    struct TQuaternion{
      
      TQuaternion(float aScalar= 0.0,
		  float aX= 0.0,  
		  float aY= 0.0,  
		  float aZ= 0.0):
	scalar(aScalar),
	x(aX),
	y(aY),
	z(aZ){}
      
      float scalar;
      float x;
      float y;
      float z;
      
    };
    
    /**
     * Struct for defining a 3x3 matrix. Elements are named eij, where
     * i is for columns and j rows. Like this:
     * --              --
     * | e11  e12   e13 |
     * | e21  e22   e23 |
     * | e31  e32   e33 |
     * --              --
     */
    struct TOrientationMatrix{
      
      TOrientationMatrix(float aE11= 0.0,float aE12= 0.0,float aE13= 0.0,
			 float aE21= 0.0,float aE22= 0.0,float aE23= 0.0,
			 float aE31= 0.0,float aE32= 0.0,float aE33= 0.0)
	:e11(aE11),
	 e12(aE12),
	 e13(aE13),
	 e21(aE21),
	 e22(aE22),
	 e23(aE23),
	 e31(aE31),
	 e32(aE32),
	 e33(aE33){}
      
      
      float e11;
      float e12;
      float e13;
      float e21;
      float e22;
      float e23;
      float e31;
      float e32;
      float e33;
      
    };

    /** Information required for reply identification.
     */
    struct TReplyInfo {
      TReplyInfo(int aSenderId= 0, int aMsgId= 0) :
	senderId(aSenderId),
	msgId(aMsgId){}

      int32_t senderId;
      int32_t msgId;
    };
    
    struct TCommand {
      TCommand(EIMUCommand aCmd = KCommandUnknown) 
	: cmd(aCmd) {}
      
      uint32_t cmd; ///< Command value
    };
  }


}

#endif ///< _MACI_IMUTYPES_HPP_
